依照昨天範例我們繼續寫下去
# -*- coding: utf-8 -*-
from odoo import api, models, fields
from odoo.exceptions import ValidationError
class ResStudent(models.Model):
_name = 'res.student'
_inherit = 'res.partner'
_description = 'Student'
nickname = fields.Char(string='綽號')
math_score = fields.Float(string='數學成績')
chinese_score = fields.Float(string='國文成績')
avg_score = fields.Float(string='學期平均', compute='_compute_score')
birthday = fields.Date(string='生日', required=True)
school_id = fields.Many2one('res.company', string='所屬學校')
school_city = fields.Char(string='所在城市', related='school_id.city')
senior_id = fields.Many2one('res.student', string='直屬學長姐')
junior_ids = fields.One2many('res.student', 'senior_id', string='直屬學弟妹')
teacher_ids = fields.Many2many('res.partner', string='指導老師', domain=[('is_company', '!=', True)])
gender = fields.Selection([("male", "男"), ("female", "女"), ("other", "其他")], string='性別')
is_leadership = fields.Boolean(default=False)
is_active = fields.Boolean(default=True)
channel_ids = fields.Many2many('mail.channel', 'mail_channel_profile_partner', 'partner_id', 'channel_id', copy=False)
@api.depends('math_score', 'chinese_score')
def _compute_score(self):
for record in self:
record.avg_score = (record.math_score + record.chinese_score) / 2
@api.onchange('school_id')
def _onchange_shcool(self):
for record in self:
record.school_city = record.school_id.city
@api.constrains('math_score', 'chinese_score')
def _validate_score(self):
for record in self:
if record.math_score < 0 or record.chinese_score < 0:
raise ValidationError(_("分數必須大於零"))
@api.model
def create(self, values):
if values.get('is_active') is False:
values.update({
'is_leadership': False
})
return super(ResStudent, self).create(values)
透過ODOO提供的裝飾器來實現不同用途的方法,介紹常用的裝飾器
規定fields要符合設定條件,否則無法新增或修改。
@api.constrains('math_score', 'chinese_score')
def _validate_score(self):
for record in self:
if record.math_score < 0 or record.chinese_score < 0:
raise ValidationError(_("分數必須大於零"))
如範例所示,當其中一項分數小於零時便會報出錯誤提示,但要注意兩點,
teacher_id.mejor != math
,老師科目不能等於數學,此裝飾器並不會有任何效果。常用於compute fields,當指定的field更改時會觸發method。
@api.depends('math_score', 'chinese_score')
def _compute_total(self):
for record in self:
record.avg_score = (record.math_score + record.chinese_score) / 2
當成績改變時,平均成績也會重新計算,同樣只作用於odoo view表層,直接更改的時候不會觸發。
與@api.depends
相似,當指定的field會觸發method
@api.onchange('school_id')
def _onchange_shcool(self):
for record in self:
record.school_city = record.school_id.city
當所選學校改變時,所在城市會跟著改變,有些要注意的地方:
@api.depends
則沒有這個限制。return {
'warning': {'title': "Warning", 'message': "What is this?", 'type': 'notification'},
}
one2many
和 many2many
field 無法透過此方法修改。self代表Model本身,與model recordset無關的方法,如: create method
@api.model
def create(self, values):
return super(ResPartner, self).create(values)
env裡存了許多快取可供使用者查詢及修改,日後也會透過此方法對DB做操作。
user: 目前使用的帳戶
self.env.user
model: 獲取指定model
self.env['res.partner'] #res_partner為model name
lang: 獲取當前語
self.env.lang
company: 獲取當前company branch
self.env.company
companies:獲取此user access的所有company branch
self.env.companies
Decorators與Environment就介紹到這邊,明天我們來介紹model內的ORM method。